﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using SilverlightClient.ServiceReferenceLogin;
using System.IO;
using SilverlightClient.ServiceReferenceVideo;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace SilverlightClient
{
    public partial class AdministradorVideos : Page
    {
        private Usuario usuario = null;
        ObservableCollection<UploadFile> _files;
        ObservableCollection<Evento> _eventos;
        ObservableCollection<Video> _videosNoAsignados;
        ObservableCollection<Video> _videosAsignados; 
        const int CHUNKSIZE = 30000; //30KB

        public AdministradorVideos(Usuario usuarioIn)
        {
            InitializeComponent();
            usuario = usuarioIn;
            if (Utilities.EsAdminSeguidor(usuario))
            {
                btnMultimedia.Visibility = Visibility.Visible;
            }
            else 
            {
                btnMultimedia.Visibility = Visibility.Collapsed;
            }
            _files = new ObservableCollection<UploadFile>();
            _videosNoAsignados = new ObservableCollection<Video>();
            _videosAsignados = new ObservableCollection<Video>();
            CargarEventos();    

        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private void CargarEventos()
        {
            try
            {
                VideoServicesClient service = new VideoServicesClient();
                service.GetEventosCompleted += new EventHandler<GetEventosCompletedEventArgs>(VideoServicesClient_GetEventosCompleted);
                service.GetEventosAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void VideoServicesClient_GetEventosCompleted(object sender, GetEventosCompletedEventArgs e)
        {
            try{
                _eventos = e.Result;

                if (_eventos != null && _eventos.Count>0)
                {
                    dataGridEventos.ItemsSource = _eventos;
                    dataGridEventos.SelectedIndex = 0;
                    VideoServicesClient service = new VideoServicesClient();
                    service.GetVideosPorEventoCompleted += new EventHandler<GetVideosPorEventoCompletedEventArgs>(VideoServicesClient_GetVideosPorEventoCompleted);
                    service.GetVideosPorEventoAsync(((Evento)dataGridEventos.SelectedItem).Id);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnUploadFile_Click(object sender, RoutedEventArgs e)
        {           
            OpenFileDialog d = new OpenFileDialog();
            d.Filter = "Video Files( *.wmv) |*.wmv";
            d.Multiselect = true;
            if (d.ShowDialog() == true)
            {
                foreach (FileInfo f in d.Files)
                {
                    UploadFile file = _files.SingleOrDefault(m => m.Name == f.Name);
                    if (file == null)
                    {
                        file = new UploadFile();
                        file.Name = f.Name;
                        Stream s = f.OpenRead();
                        file.Size = s.Length / 1000;
                        int chunkSize = (int)s.Length;
                        file.Contents = new List<byte[]>();
                        while (s.Position > -1 && s.Position < s.Length)
                        {
                            if (s.Length - s.Position >= CHUNKSIZE)
                                chunkSize = CHUNKSIZE;
                            else
                                chunkSize = (int)(s.Length - s.Position);

                            byte[] fileBytes = new byte[chunkSize];
                            int byteCount = s.Read(fileBytes, 0, chunkSize);
                            file.Contents.Add(fileBytes);
                        }
                        s.Close();
                        _files.Add(file);
                        SendFile(file, false);
                    }
                }
                FileList.ItemsSource = _files;
                FileList.Visibility = Visibility.Visible;
            }
        }

        private void SendFile(UploadFile file, bool append)
        {
            VideoServicesClient service = new VideoServicesClient();
            service.DoUploadCompleted += new EventHandler<DoUploadCompletedEventArgs>(VideoServicesClient_DoUploadCompleted);
            service.DoUploadAsync(file.Name, file.Contents[0], append);
        }

        void VideoServicesClient_DoUploadCompleted(object sender, DoUploadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                SilverlightClient.ServiceReferenceVideo.UploadFile fi = e.Result;
                UploadFile f = _files.Single(m => m.Name == fi.Name);
                if (f.Contents.Count > 0)
                {
                    f.Contents.RemoveAt(0);
                }
                if (f.Contents.Count == 0)
                {
                    f.UploadPercentage = 100;
                    f.Loaded = true;
                    CrearVideoBD(f.Name);
                }
                else
                {
                    f.UploadPercentage = 100 - Convert.ToInt16(((f.Contents.Count - 1) * CHUNKSIZE + f.Contents[f.Contents.Count - 1].Length) * 0.1 / f.Size);
                    SendFile(f, true);
                }
                f.FileStoreUrl = fi.FileStoreUrl;
            }
            else
                MessageBox.Show(e.Error.Message);
        }

        private void CrearVideoBD(string fileName)
        {
            VideoServicesClient service = new VideoServicesClient();
            service.CrearVideoCompleted += new EventHandler<CrearVideoCompletedEventArgs>(VideoServicesClient_CrearVideoCompleted);
            service.CrearVideoAsync(fileName);
        }

        void VideoServicesClient_CrearVideoCompleted(object sender, CrearVideoCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                try
                {
                    ObservableCollection<Video> videosTotales = e.Result;

                    if (videosTotales != null)
                    {
                        BindVideosNoAsignados(videosTotales);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void dataGridEventos_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            VideoServicesClient service = new VideoServicesClient();
            service.GetVideosPorEventoCompleted += new EventHandler<GetVideosPorEventoCompletedEventArgs>(VideoServicesClient_GetVideosPorEventoCompleted);
            service.GetVideosPorEventoAsync(((Evento)e.AddedItems[0]).Id);
        }

        void VideoServicesClient_GetVideosPorEventoCompleted(object sender, GetVideosPorEventoCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                try
                {
                    ObservableCollection<Video> videosAsignados = e.Result;
                    _videosAsignados.Clear();

                    if (videosAsignados != null)
                    {
                        _videosAsignados= videosAsignados;
                        lstVideosAsignados.ItemsSource = _videosAsignados;
                    }

                    GetVideosNoAsignados();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void GetVideosNoAsignados()
        {
            VideoServicesClient service = new VideoServicesClient();
            service.GetVideosCompleted += new EventHandler<GetVideosCompletedEventArgs>(VideoServicesClient_GetVideosCompleted);
            service.GetVideosAsync();
        }

        void VideoServicesClient_GetVideosCompleted(object sender, GetVideosCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                try
                {
                    ObservableCollection<Video> videosTotales = e.Result;
                    BindVideosNoAsignados(videosTotales);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void BindVideosNoAsignados(ObservableCollection<Video> videosTotales)
        {
            _videosNoAsignados.Clear();
            foreach (Video video in videosTotales)
            {
                if (!_videosAsignados.Contains(video, new VideoComparer()))
                {
                    _videosNoAsignados.Add(video);
                }
            }
            lstVideosNoAsignados.ItemsSource = _videosNoAsignados;
        }

        private void btnAsignar_Click(object sender, RoutedEventArgs e)
        {
            var videosSeleccionados = lstVideosNoAsignados.SelectedItems;
            if (videosSeleccionados != null && videosSeleccionados.Count > 0)
            {
                int eventoId = ((Evento)dataGridEventos.SelectedItem).Id;
                for (int i=0; i < videosSeleccionados.Count; i++)
                {
                    Video video = (Video)videosSeleccionados[i];
                    AsignarVideo(video.Id, eventoId);
                    _videosNoAsignados.Remove(video);
                    _videosAsignados.Add(video);
                }
            }
        }

        private void AsignarVideo(int idVideo, int idEvento)
        {
            VideoServicesClient service = new VideoServicesClient();
            service.AsociarVideoEventoCompleted += new EventHandler<AsyncCompletedEventArgs>(VideoServicesClient_AsociarVideoEventoCompleted);
            service.AsociarVideoEventoAsync(idVideo, idEvento);
        }

        void VideoServicesClient_AsociarVideoEventoCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void btnDesasignar_Click(object sender, RoutedEventArgs e)
        {
            var videosSeleccionados = lstVideosAsignados.SelectedItems;
            if (videosSeleccionados != null && videosSeleccionados.Count > 0)
            {
                int eventoId = ((Evento)dataGridEventos.SelectedItem).Id;
                for (int i = 0; i < videosSeleccionados.Count; i++)
                {
                    Video video = (Video)videosSeleccionados[i];
                    DesasignarVideo(video.Id, eventoId);
                    _videosAsignados.Remove(video);
                    _videosNoAsignados.Add(video);
                }
            }
        }

        private void DesasignarVideo(int idVideo, int idEvento)
        {
            VideoServicesClient service = new VideoServicesClient();
            service.EliminarVideoEventoCompleted += new EventHandler<AsyncCompletedEventArgs>(VideoServicesClient_EliminarVideoEventoCompleted);
            service.EliminarVideoEventoAsync(idVideo, idEvento);
        }

        void VideoServicesClient_EliminarVideoEventoCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                try
                {                   
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void btnMultimedia_Click(object sender, RoutedEventArgs e)
        {
            Grid root = Application.Current.RootVisual as Grid;
            if (root != null)
            {
                root.Children.RemoveAt(0);
                root.Children.Add(new MainPage(usuario));
            }
        }
    }

    public class VideoComparer : IEqualityComparer<Video>
    {

        public bool Equals(Video x, Video y)
        {
            if (Object.ReferenceEquals(x, y)) return true;

            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;

            return x.Id.Equals(y.Id);
        }

        public int GetHashCode(Video video)
        {
            if (Object.ReferenceEquals(video, null)) return 0;

            int hashVideoId = video.Id.GetHashCode();
            return hashVideoId;
        }

    }


    public class UploadFile : INotifyPropertyChanged
    {
        public string Name { get; set; }
        public double Size { get; set; }
        int _UploadPercentage;
        public int UploadPercentage
        {
            get
            {
                return _UploadPercentage;
            }
            set
            {
                _UploadPercentage = value;
                NotifyChange("UploadPercentage");
            }
        }
        string _FileStoreUrl;
        public string FileStoreUrl
        {
            get { return _FileStoreUrl; }
            set
            {
                _FileStoreUrl = value;
                NotifyChange("FileStoreUrl");
            }
        }
        public byte[] FileContent { get; set; }

        public List<byte[]> Contents { get; set; }
        private bool _Loaded;
        public bool Loaded
        {
            get { return _Loaded; }
            set
            {
                _Loaded = value;
                NotifyChange("Loaded");
            }
        }
        protected void NotifyChange(params string[] properties)
        {
            if (PropertyChanged != null)
            {
                foreach (string p in properties)
                    PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

}
